package com.xjrsoft.module.authority.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.model.result.R;
import com.xjrsoft.common.page.ConventPage;
import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.common.utils.RedisUtil;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.module.authority.dto.AddDataAuthDto;
import com.xjrsoft.module.authority.dto.DataAuthListDto;
import com.xjrsoft.module.authority.dto.DataAuthPageDto;
import com.xjrsoft.module.authority.dto.UpdateDataAuthDto;
import com.xjrsoft.module.authority.entity.DataAuth;
import com.xjrsoft.module.authority.service.IDataAuthService;
import com.xjrsoft.module.authority.vo.DataAuthListVo;
import com.xjrsoft.module.authority.vo.DataAuthPageVo;
import com.xjrsoft.module.authority.vo.DataAuthVo;
import com.xjrsoft.module.organization.entity.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
 * <p>
 * 数据权限表 前端控制器
 * </p>
 *
 * @author tzx
 * @since 2023-02-27
 */
@RestController
@RequestMapping(GlobalConstant.AUTHORITY_MODULE_PREFIX + "/data-auth")
@Api(value = GlobalConstant.ORGANIZATION_MODULE_PREFIX + "/data-auth", tags = "数据权限")
@AllArgsConstructor
public class DataAuthController {

    private IDataAuthService authService;

    private RedisUtil redisUtil;

    @GetMapping(value = "/list")
    @ApiOperation(value = "数据权限(不分页)")
    public R list(@Valid DataAuthListDto dto) {
        //因为多表关联 会有多个表都使用了id字段，  所以必须专门指定主表的Id
        List<DataAuthListVo> list = authService.selectJoinList(DataAuthListVo.class,
                new MPJLambdaWrapper<DataAuth>()
                        .disableSubLogicDel()
                        .and(StrUtil.isNotBlank(dto.getKeyword()), wrapper -> wrapper.like(DataAuth::getName, dto.getKeyword()).or().like(DataAuth::getCode, dto.getKeyword()))
                        .select(DataAuth::getId)
                        .select(DataAuth.class, x -> VoToColumnUtil.fieldsToColumns(DataAuthListVo.class).contains(x.getProperty()))
                        .leftJoin(User.class, User::getId, DataAuth::getCreateUserId, ext -> ext.selectAs(User::getName, DataAuthListVo::getCreateUserName))
                        .leftJoin(User.class, User::getId, DataAuth::getModifyUserId, ext -> ext.selectAs(User::getName, DataAuthListVo::getModifyUserName))
//                        .leftJoin(DataAuthRelation.class, DataAuthRelation::getDataAuthId, DataAuth::getId)
//                        .selectCollection(DataAuthRelation.class, DataAuth::getAuthObjectList)
                        .orderByDesc(DataAuth::getCreateDate)
//                        .leftJoin(User.class, User::getId, DataAuthRelation::getObjectId, ext -> ext.selectCollection(User::getName,Data))
        );

        return R.ok(list);
    }

    @GetMapping(value = "/page")
    @ApiOperation(value = "数据权限(分页)")
    public R page(@Valid DataAuthPageDto dto) {
        //因为多表关联 会有多个表都使用了id字段，  所以必须专门指定主表的Id
        IPage<DataAuthPageVo> page = authService.selectJoinListPage(ConventPage.getPage(dto), DataAuthPageVo.class,
                new MPJLambdaWrapper<DataAuth>()
                        .disableSubLogicDel()
                        .and(StrUtil.isNotBlank(dto.getKeyword()), wrapper -> wrapper.like(DataAuth::getName, dto.getKeyword()).or().like(DataAuth::getCode, dto.getKeyword()))
                        .select(DataAuth::getId)
                        .select(DataAuth.class, x -> VoToColumnUtil.fieldsToColumns(DataAuthPageVo.class).contains(x.getProperty()))
                        .leftJoin(User.class, User::getId, DataAuth::getCreateUserId, ext -> ext.selectAs(User::getName, DataAuthListVo::getCreateUserName))
                        .leftJoin(User.class, User::getId, DataAuth::getModifyUserId, ext -> ext.selectAs(User::getName, DataAuthListVo::getModifyUserName))
//                        .leftJoin(DataAuthRelation.class, DataAuthRelation::getDataAuthId, DataAuth::getId)
//                        .selectCollection(DataAuthRelation.class, DataAuth::getAuthObjectList)
                        .orderByDesc(DataAuth::getCreateDate)
//                        .leftJoin(User.class, User::getId, DataAuthRelation::getObjectId, ext -> ext.selectCollection(User::getName,Data))
        );


        PageOutput<DataAuthPageVo> pageOutput = ConventPage.getPageOutput(page);

        return R.ok(pageOutput);
    }

    @GetMapping(value = "/info")
    @ApiOperation(value = "根据id查询数据权限信息")
    public R info(@RequestParam Long id) {

        DataAuth dataAuth = authService.getByIdDeep(id);
        if (dataAuth == null) {
            R.error("找不到此权限数据！");
        }
        return R.ok(BeanUtil.toBean(dataAuth, DataAuthVo.class));
    }

    @PostMapping
    @ApiOperation(value = "新增权限")
    @Transactional(rollbackFor = Exception.class)
    public R add(@Valid @RequestBody AddDataAuthDto dto) {
        long count = authService.count(Wrappers.<DataAuth>query().lambda().eq(DataAuth::getName, dto.getName()).or().eq(DataAuth::getCode, dto.getCode()));
        if (count > 0) {
            return R.error("数据权限名称或编码已存在！");
        }
        return R.ok(authService.add(dto));
    }

    @PutMapping
    @ApiOperation(value = "修改权限")
    @Transactional(rollbackFor = Exception.class)
    public R update(@Valid @RequestBody UpdateDataAuthDto dto) {

        long count = authService.count(Wrappers.<DataAuth>query().lambda()
                .eq(DataAuth::getCode, dto.getCode())
                .ne(DataAuth::getId, dto.getId()));

        if (count > 0) {
            return R.error("编码已经存在！");
        }
        return R.ok(authService.edit(dto));
    }

    @DeleteMapping
    @ApiOperation(value = "删除用户(可批量)")
    public R delete(@RequestBody List<Long> ids) {

        boolean isSuccess = authService.removeBatchByIds(ids);
        redisUtil.set(GlobalConstant.DATA_AUTH_CACHE_KEY, authService.list());
        return R.ok(isSuccess);
    }


    @GetMapping("/auth-objects")
    @ApiOperation(value = "查询数据权限授权对象")
    public R getAuthObjectsInfo(@RequestParam Long id) {
        return R.ok(authService.getAuthObjectsInfo(id));
    }
}
